package com.ssm.yin.util;

import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * @Package: cn.com.yin.controller.cn.com.yin.utils
 * @ClassName: FileToUpload
 * @Author: Yin
 * @Date: 18:59
 * @Description: 基于SpringMVC的文件传输工具类，上传文件和下载文件
 */
public class WebFileTransferUtil {

    /**
     * @param serverPath：服务器上的抽象路径<br>
     * @param files：获取到的文件数据，MultipartFile是SpringMVC集成commons-fileupload的二次封装。能更好的对文件操作。<br>
     * @param request：请求对象<br>
     * @return boolean
     * @Description：服务器的路径不要 [/directory]，直接 [directory]即可，因为它以及做了 '/' 拼接<br>
     */
    public static boolean FilesUpload(String serverPath , MultipartFile[] files, HttpServletRequest request) {
        try {
            ServletContext servletContext = request.getServletContext();
            // 获取服务器上某个文件的真实路径（这里获取的是，保存上传文件的文件目录）
            String realPath = servletContext.getRealPath("/"+serverPath);
            // 创建一个文件对象
            File directory = new File(realPath);
            // 判断文件目录是否存在，不存在则创建
            if (!directory.exists())
                directory.mkdirs();  // mkdirs() 要么创建成功，要么创建失败。创建多个文件目录。

            for (int i = 0; i < files.length; i++) {
                if(!files[i].isEmpty()){ // 判断是否接收了文件
                    // 完整的文件名 String originalFilename = files[i].getOriginalFilename();
                    // 文件大小 long size = files[i].getSize();
                    // 文件字节数组 byte[] bytes = files[i].getBytes();
                    // 文件类型 String contentType = files[i].getContentType();
                    String suffix = files[i].getOriginalFilename().split("\\.")[1];// 获取文件后缀
                    // 进行文件的传输，用transferTo()方法的话，上面的创建文件就显的多此一举
                    files[i].transferTo(new File(directory, System.currentTimeMillis() + "." + suffix)); // 一般传输文件不用这个方法
                }
            }
        }catch (IOException e){
            e.printStackTrace();
            return false;
        }
        return true;
    }


    /**
     * @param serverPath：服务器上的抽象路径，它可以是文件目录，也可以是文件
     * @param request：请求对象
     * @param response：响应对象
     * @return boolean
     * @Description：服务器的路径不要 [/directory]，直接 [directory]即可，因为它以及做了 '/' 拼接
     */
    public static boolean FileDown(String serverPath , HttpServletRequest request, HttpServletResponse response){
        ServletContext servletContext = request.getServletContext();
        // 从服务器上获取该文件路径
        String realPath = servletContext.getRealPath("/"+serverPath);

        // 将此文件路径创建为一个File类
        File file = new File(realPath);
        String filename = file.getName();// 获取文件名

        try {
            // 判断此抽象文件路径是否存在。
            if (file.isFile()){
                // 创建一个字节输入流，读取服务器上的文件
                FileInputStream inputStream = null;
                inputStream = new FileInputStream(file);
                // 将读取到的文件，传输到客户端
                String mimeType = servletContext.getMimeType(filename); // 获取文件类型
                response.setHeader("Content-Type",mimeType); // 设置响应的内容（文件）类型
                // 显示传输的文件内容（文件名和文件类型）
                response.setHeader("Content-Disposition","attachment;filename="+filename);

                // 获取一个输出流，因为是响应回去。当然是从响应对象获取啦
                ServletOutputStream outputStream = response.getOutputStream();

                // 读取文件
                byte[] b = new byte[5242880] ; // 字节缓冲数组 5MB
                int len = 0 ; // 读取到的字节
                while( (len = inputStream.read(b)) != -1){
                    outputStream.write(b,0,len);
                }
                // 关闭输入流，释放资源
                inputStream.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
}

/*
class UtilFile{
    // 完整的文件名
    private String originalFilename;
    // 文件大小
    private String size;
    // 文件字节数组
    private byte[] bytes;
    // 文件类型
    private String contentType;
    // 文件后缀
    private String suffix;
}*/
